/*
 * Copyright 2010 - 2011, The PLDesktop Development Team
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */

#ifndef PLVIRTUAL_PAGE_WITHOUT_PAE_4k_H
#define PLVIRTUAL_PAGE_WITHOUT_PAE_4k_H

#include <machine/pc/memory/virtualpageinterface.h>

/**
 * Implement the paging methode without PAE enabled and with 4k pages.
 */
class PLVirtualPageWithoutPAE4k : public PLVirtualPageInterface {
public:
	/**
	 * Constructor.
	 */
	PLVirtualPageWithoutPAE4k();
	/**
	 * Init the virtual memory management.
	 * This also create the page directory for the kernel and set it as
	 * the curent page directory.
	 *
	 * @param virtualpagemanager The pointer to the virtual page manager.
	 */
	void init(PLVirtualPageManager *virtualpagemanager);
	/**
	 * Get the physical address of a virtual address.
	 *
	 * @param virtualaddr The virtual address to get the physical address for.
	 * @return The resulting physical address.
	 */
	void *getPhysicalAddress(void *virtualaddr);
	/**
	 * Map a physical page to a virtual address.
	 *
	 * @param physaddr Physical address.
	 * @param virtualaddr Virtual address to map to.
	 * @param flagsTable Flags for the table.
	 */
	void mapPage(void *physaddr, void *virtualaddr, int flagsTable);
	/**
	 * Set other flags for the virtual address.
	 *
	 * @param virtualaddr The virtual address to set.
	 * @param flagsTable The new flags to set.
	 */
	void setFlags(void *virtualaddr, int flagsTable);
	/**
	 * Get the directory index of a virtual address.
	 *
	 * @param address The address to get the index for.
	 * @return The index in the directory.
	 */
	inline uint32_t getDirectoryIndex(uint32_t address);
	/**
	 * Get the table index of a virtual address.
	 *
	 * @param address The address to get the index for.
	 * @return The index in the table.
	 */
	inline uint32_t getTableIndex(uint32_t address);
	/**
	 * Get the page size for the current virtual memory management.
	 *
	 * @return The page size.
	 */
	inline int pageSize();
};

uint32_t PLVirtualPageWithoutPAE4k::getDirectoryIndex(uint32_t address) {
	return (address >> 22);
}

uint32_t PLVirtualPageWithoutPAE4k::getTableIndex(uint32_t address) {
	return ((address >> 12) & 0x3FF);
}

int PLVirtualPageWithoutPAE4k::pageSize() {
	return 4096;
}

#endif
